home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Technotools
/
Technotools (Chestnut CD-ROM)(1993).ISO
/
lang_c
/
cug189
/
pr.c
< prev
next >
Wrap
Text File
|
1985-08-21
|
8KB
|
320 lines
/*
* pr.c: detabbing file printer -
*
* usage: pr [options] [file1 file2 ...]
* options:
* -b# begin printing with page #
* -c# print # copies
* -d delete file after printing
* -e# end printing with page #
* -hs use title s instead of filename (NULL = no header)
* -l print with line numbers
* -m# print with a left margin of # spaces
* -n# print # lines per page (header xtra)
* -s# print with spacing of # lines
* -t# set tabs every # spaces (default 4)
* -w# define page width (default 256)
*
* Other than tabs, all control characters are suppressed.
*
* Adapted from Software Tools by Chuck Allison - May 1985
*/
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <types.h> /* MWC only */
#define inrange(x) (start <= x && x <= stop)
#define getnum(x) x = atoi(s+1); goto next_arg
#define MAXINT 32767
#define MAXLINE 256
#define yes 1
#define no 0
/* ..set default parameters.. */
int number = no,
delete = no,
print_lines_pp = 55,
text_lines_pp = 55,
margin = 3,
spacing = 1,
tabspace = 4,
width = 256,
headers = yes,
copies = 1,
start = 1,
stop = MAXINT;
static tabstops[MAXLINE];
time_t time_val;
static char timestr[25], title[36] = "";
extern char *trim_fspec();
main(argc,argv)
int argc;
char *argv[];
{
int hour;
register char *s;
/* ..process switches.. */
while (--argc && (**++argv == '-'|| **argv == '/'))
{
for (s = *argv+1; *s; ++s)
switch(tolower(*s))
{
case 'b':
getnum(start);
case 'd':
delete = yes;
break;
case 'e':
getnum(stop);
case 'h':
if (s[1])
{
strcpy(title,++s);
goto next_arg;
}
else
{
headers = no;
break;
}
case 'l':
number = yes;
break;
case 'm':
getnum(margin);
case 'n':
getnum(print_lines_pp);
case 's':
getnum(spacing);
case 't':
getnum(tabspace);
case 'c':
getnum(copies);
case 'w':
getnum(width);
default :
fprintf(stderr,"---> ERROR: bad switch: -%c\n",*s);
exit(1);
}
next_arg: /* ..cycle on outer for().. */ ;
}
/* ..initialize tab settings.. */
settabs();
/* ..validate line spacing.. */
if (spacing <= 0 || print_lines_pp <= spacing)
{
fprintf(stderr,"---> ERROR: Spacing invalid\n");
exit(1);
}
text_lines_pp = 1 + (print_lines_pp - 1) / spacing;
/* ..get date and time.. */
time(&time_val);
strcpy(timestr,ctime(&time_val));
timestr[24] = '\0'; /* ..zap newline.. */
/* ..Replace seconds with am/pm.. */
timestr[16] = ' ';
hour = 10*(timestr[11] - '0') + (timestr[12] - '0');
if (hour >= 12)
{
timestr[17] = 'p';
if (hour > 12)
{
hour -= 12;
timestr[12] = hour%10 + '0';
timestr[11] = (hour /= 10) ? hour + '0' : ' ';
}
}
else
{
timestr[17] = 'a';
if (hour == 0)
{
timestr[11] = '1';
timestr[12] = '2';
}
else if (timestr[11] == '0')
timestr[11] = ' ';
}
timestr[18] = 'm';
/* ..process files.. */
if (argc == 0)
process(title);
else
{
/* ..print each file.. */
for (; *argv; ++argv)
if (freopen(*argv,"r",stdin) != NULL)
{
process((strlen(title) == 0) ? *argv : title);
if (delete)
if (unlink(*argv) != 0)
fprintf(stderr,"---> WARNING: can't delete %s\n",*argv);
else
fprintf(stderr,"---> %s deleted.\n",*argv);
}
else
fprintf(stderr,"---> ERROR: can't process %s\n",*argv);
}
}
process(f)
char *f;
{
register i;
for (i = 0; i < copies; ++i)
{
rewind(stdin);
pr(f);
}
}
pr(name)
char *name;
{
register lineno, i;
int pageno, offset;
char line[MAXLINE];
extern char *rindex();
offset = 0;
pageno = 1;
lineno = 1;
fprintf(stderr,"---> printing %s...\n",name);
/* ..trim a long file name.. */
trim_fspec(name,name,30);
/* ..output initial header.. */
if (inrange(pageno))
if (headers)
header(name,pageno);
else
printf("\n\n\n\n");
while (fgets(line,MAXLINE-1,stdin) != NULL)
{
/* ..check page range.. */
if (pageno > stop)
return;
if (lineno == 0)
{
lineno = 1;
if (inrange(pageno))
if (headers)
header(name,pageno);
else
printf("\n\n\n\n");
}
if (pageno > stop)
return;
/* ..print line, with number, if requested.. */
if (inrange(pageno))
{
do_margin();
if (number)
printf("%5d ",offset+lineno);
else
printf(" ");
detab(line);
if (lineno+1 <= text_lines_pp)
for (i = 1; i < spacing; ++i)
putchar('\n');
}
/* ..check for page break.. */
if (++lineno > text_lines_pp)
{
if (inrange(pageno))
putchar('\f');
offset += text_lines_pp;
++pageno;
lineno = 0;
}
}
/* ..form-feed after last partial page.. */
if (inrange(pageno))
if (lineno > 0)
putchar('\f');
}
header(file,page)
char *file;
int page;
{
register i;
putchar('\n');
do_margin();
for (i = 0; i < 75; ++i)
putchar('-');
putchar('\n');
do_margin();
printf("%-36.36s%-30.30sPage%5d",file,timestr,page);
putchar('\n');
do_margin();
for (i = 0; i < 75; ++i)
putchar('-');
printf("\n\n\n");
}
detab(line)
char *line;
{
register i, col;
col = 0;
/* ..note: line[] has a terminating '\n' per fgets().. */
for (i = 0; col < width-margin-(number?7:2) && i < strlen(line); ++i)
if (line[i] == '\t')
do
{
/* ..tab.. */
putchar(' ');
++col;
} while (!tabstops[col]);
else if (line[i] == '\n' || isprint(line[i]))
{
putchar(line[i]);
++col;
}
if (i < strlen(line))
putchar('\n');
}
settabs()
{
register i;
tabstops[0] = 0;
for (i = 1; i < MAXLINE; ++i)
tabstops[i] = (i % tabspace == 0);
}
do_margin()
{
register i;
for (i = 0; i < margin; ++i)
putchar(' ');
}
putchar(' ');
++col;
} while (!tabstops[col]);
else if (line[